<template>
  <div id="container">
    <el-form ref="modelFormRef" :model="modelForm" :rules="rules" label-position="top" size="default" status-icon>
      <el-collapse v-model="activeNames">
        <el-collapse-item name="1">
          <template #title>
            <div class="dflex justify-between">
              <div class="dflex">
                <!-- <img :src="Arrow_3" alt="" srcset=""> -->
                <!-- <img :src="AddIcon" @click.stop="handleOpenTrainAndMemory(true, false)" alt="" srcset="" /> -->
                <div class="ft-16">训练数据</div>
              </div>
            </div>
          </template>

          <template #default>
            <div v-loading="loading">
              <div class="text-right">
                <el-button
                  :icon="Plus"
                  @click.stop="handleOpenTrainAndMemory(true, false)"
                  type="danger"
                  class="add-btn"
                  >添加训练数据</el-button
                >
              </div>

              <div class="dflex justify-between" v-for="item in trainingList" :key="item.id">
                <div class="arrIcon dflex">
                  <div class="avatar-img">
                    <img :src="Arrow" alt="" srcset="" />
                  </div>
                  <div class="f14333">{{ item.knowledge.name }}</div>
                </div>
                <div>
                  <!-- <img :src="Arrow_1" alt="" srcset="" @click="handleCopyTrainList(item.knowledge.id)"> -->
                  <img :src="Arrow_2" alt="" srcset="" @click="handleDeleteTrainList(item)" />
                </div>
              </div>
            </div>
          </template>
        </el-collapse-item>

        <el-collapse-item name="2">
          <template #title>
            <!-- 记忆体 -->
            <div class="dflex justify-between">
              <div class="dflex">
                <!-- <img :src="AddIcon" @click.stop="handleOpenTrainAndMemory(false, true)" alt="" srcset="" /> -->
                <!-- <img :src="Arrow_3" alt="" srcset=""> -->
                <div class="ft-16">记忆体</div>
              </div>
            </div>
          </template>

          <template #default>
            <!-- <img :src="AddIcon"   alt="" srcset="" /> -->
            <div class="text-right">
              <el-button :icon="Plus" @click.stop="handleOpenTrainAndMemory(false, true)" type="danger" class="add-btn"
                >添加记忆体</el-button
              >
            </div>
            <el-card v-loading="loading" class="dMemory" shadow="never" v-for="item in memoryList" :key="item.robot_id">
              <div class="dflex flexStart justify-between">
                <div class="l-title">{{ item.question }}</div>
                <el-popover
                  ref="morePopover"
                  popper-class="morePopoverZw"
                  trigger="click"
                  placement="bottom"
                  width="60"
                  :show-arrow="false"
                >
                  <p
                    :style="{ color: 'var(--el-color-danger)', cursor: 'pointer' }"
                    @click="handleMemoryDeleteId(item.id, item.robot_id)"
                  >
                    删除
                  </p>
                  <template #reference>
                    <el-icon class="more">
                      <MoreFilled />
                    </el-icon>
                  </template>
                </el-popover>
              </div>
              <div class="l-answer">{{ item.answer }}</div>
            </el-card>
          </template>
        </el-collapse-item>

        <!-- 代理配置 -->
        <el-collapse-item name="3">
          <template #title>
            <!-- 记忆体 -->
            <div class="dflex justify-between">
              <div class="dflex">
                <img :src="Arrow_3" alt="" srcset="" />
                <div class="ml-10 ft-16">代理配置</div>
              </div>
            </div>
          </template>

          <template #default>
            <el-checkbox-group class="checkbox-group" v-model="checkboxGroup" size="small">
              <el-checkbox v-for="item in proxyList" :key="item.key" :label="item.key" :value="item.key">
                {{ item.label }}</el-checkbox
              >
            </el-checkbox-group>
          </template>
        </el-collapse-item>
        <!-- end -->
        <el-collapse-item name="4">
          <template #title>
            <!-- 记忆体 -->
            <div class="dflex justify-between">
              <div class="dflex">
                <img :src="Arrow_3" alt="" srcset="" />
                <div class="ml-10 ft-16">模型设置</div>
              </div>
            </div>
          </template>

          <template #default>
            <div class="setting-card" v-for="(item, index) in modelSettingList" :key="index">
              <div class="dflex justify-between">
                <div class="ft-16 ft-14">{{ item.label }}</div>
                <el-switch type="primary" v-model="item.isCheck" @change="(e) => handleMemory_AudioCheck(e, index)" />
              </div>
            </div>
            <!--  -->
            <el-form-item style="margin-top: 20px" label="语音模型" prop="voice_id">
              <el-select
                style="width: 100%; border-radius: 6px"
                v-model="modelForm.voice_id"
                placeholder="请选择语音模型"
              >
                <el-option v-for="item in voiceModel" :key="item.id" :label="item.name" :value="item.id" />
              </el-select>
            </el-form-item>
            <el-form-item label="智能体模型" prop="model_name">
              <el-select
                style="width: 100%; border-radius: 6px"
                v-model="modelForm.model_name"
                placeholder="请选择智能体模型"
              >
                <el-option v-for="(item, index) in yunShanModel" :key="index" :label="item.name" :value="item.name" />
              </el-select>
            </el-form-item>
            <el-form-item class="btn">
              <el-button type="primary" @click="handleModelOnSubmit(modelFormRef)" border="none"> 提交 </el-button>
            </el-form-item>
            <!-- end -->
          </template>
        </el-collapse-item>
      </el-collapse>
    </el-form>

    <!-- 添加训练模型 -->
    <el-dialog
      style="border-radius: 10px"
      v-loading="loading"
      v-if="trainVisible"
      v-model="trainVisible"
      title="添加训练数据"
      width="30%"
    >
      <div class="checkbox" v-for="item in knowledgeList" :key="item.id">
        <div :class="['checkbox-info', item.isCheck ? 'checkbox-active' : '']" @click="handleCheckList(item)">
          <div class="left">
            <div class="avatar-img">
              <img :src="Arrow" alt="" srcset="" />
            </div>
            <div class="f14333">{{ item.name }}</div>
          </div>
          <img class="right isGou" :src="IsGouPng" alt="" />
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleOpenTrainAndMemory(false, false)">取消</el-button>
          <el-button type="danger" :loading="submitBtnLoading" @click="handleTrainOnConfirm()"> 添加 </el-button>
        </span>
      </template>
    </el-dialog>
    <!-- end -->

    <!-- 添加记忆体 -->
    <el-dialog
      style="border-radius: 10px"
      class="memoryModel"
      v-if="memoryVisible"
      v-model="memoryVisible"
      title="新增记忆体"
      width="30%"
    >
      <!--知识库from -->
      <el-form ref="memoryFormRef" :rules="memoryRules" :model="memoryForm" label-position="top">
        <el-form-item prop="question">
          <el-input v-model="memoryForm.question" autocomplete="off" placeholder="请输入问题" />
        </el-form-item>
        <el-form-item prop="answer">
          <el-input v-model="memoryForm.answer" type="textarea" placeholder="请输入答案" />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleMemoryCancel(memoryFormRef)">取消</el-button>
          <el-button :loading="memoryLoading" type="danger" @click="handleOnSubmit(memoryFormRef)"> 新增 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { UpdateRobotSettingApi } from "@/api/cloud"
import { Plus } from "@element-plus/icons-vue"
import { RobotListProps } from "@/api/cloud/types/cloud"
import { APIGetAgent, APIUpAgent, knowledgeList as knowledgeListApi } from "@/api/interface"
import {
  AddMemory,
  AddTrainApi,
  DeleteRobotIdMemory,
  DeleteTrainApi,
  GetRobotIdMemoryList,
  GetTrainListApi
} from "@/api/memory"
import Arrow from "@/assets/docs/arr.svg"
import Arrow_2 from "@/assets/docs/arrow_2.svg"
import Arrow_3 from "@/assets/docs/arrow_3.svg"
// import AddIcon from "@/assets/drawing/add.png"
import IsGouPng from "@/assets/drawing/is_gou.png"
import { useDigitalStore } from "@/store/modules/digital"
import { generateRule } from "@/utils"
import debounce from "@/utils/debounce"
import { ElMessage, ElMessageBox, FormInstance, FormRules } from "element-plus"
import Pubsub from "pubsub-js"
import { computed, onBeforeUnmount, onMounted, reactive, ref } from "vue"
import { APIVoiceGetList } from "@/api/ApiSpeechModel"

interface MemoryFormProps {
  robot_id: number
  question: string
  answer: string
}

interface MemoryListProps {
  id: number
  robot_id: number
  question: string
  answer: string
  user_id: number
  status: string
}

interface KnowledgeListProps {
  id: number
  name: string
  user_id: number
  info: string
  status: string
  file_count: number
  file_size: number
  admin_nickname: string
  admin_avatar: string
  isCheck?: boolean
}

interface TrainListProps {
  id: number
  robot_id: number
  user_id: number
  knowledge_id: number
  status: string
  createtime: number
  knowledge: {
    id: number
    name: string
    user_id: number
    info: string
    status: string
  }
}

interface ModelSettingListProps {
  label: string
  value: string // 1, 开启记忆+返回语音 2, 关闭记忆+不返回语音
  isCheck: boolean
}

interface ModelFormProps {
  model_name: string // 'Yunshan-v1' | 'Yunshan-v2',
  voice_id: string
}

interface InterDataProps {
  interData: RobotListProps
}

const props = defineProps<InterDataProps>()

const isAudioCheck = computed(() => {
  return props.interData.is_audio === "1"
})
const isMemoryCheck = computed(() => {
  return props.interData.is_memory === "1"
})
const activeNames = ref<string>("3")
const knowledgeId = ref<number>(1)
const trainVisible = ref<boolean>(false)
const memoryVisible = ref<boolean>(false)
const memoryLoading = ref<boolean>(false)
const loading = ref<boolean>(false)
const submitBtnLoading = ref<boolean>(false)
const knowledgeList = ref<KnowledgeListProps[]>([]) // 知识库列表
const trainingList = ref<TrainListProps[]>([]) // 训练列表
const memoryList = ref<MemoryListProps[]>([]) // 记忆体列表
const memoryFormRef = ref<FormInstance>() // 记忆体表单实例
const modelFormRef = ref<FormInstance>() // 表单实例
const proxyList = ref<any>() // 代理列表
const voiceModel = ref<any>([]) // 语音模型列表
const memoryForm = reactive<MemoryFormProps>({
  robot_id: 1,
  question: "",
  answer: ""
})
const modelForm = ref<ModelFormProps>({
  voice_id: props.interData.voice_id,
  model_name: props.interData.model_name
} as ModelFormProps)

const checkboxGroup = ref([])

const upDataVoiceModel = () => {
  const modelList = ["AU", "CHAT", "BARD"]
  modelList.forEach(async (e) => {
    const { data } = await APIVoiceGetList({ model: e, page: 1 })
    data.list.forEach((k: any) => {
      voiceModel.value.push(k)
    })
  })
}

const modelSettingList = ref<ModelSettingListProps[]>([
  {
    label: "是否开启记忆",
    value: props.interData.is_memory ? String(props.interData.is_memory) : "2",
    isCheck: isMemoryCheck.value
  },
  {
    label: "是否返回语音",
    value: props.interData.is_audio ? String(props.interData.is_audio) : "2",
    isCheck: isAudioCheck.value
  }
])

const rules = reactive<FormRules<ModelFormProps>>({
  model_name: generateRule("语音模型"),
  voice_id: generateRule("智能体模型")
})

const { yunShanModel } = useDigitalStore()

const initMemoryList = async (robot_id: string) => {
  loading.value = true
  try {
    const { data, code } = await GetRobotIdMemoryList({ page: 1, robot_id })
    if (code === 200) {
      memoryList.value = data.list
    }
  } catch (error) {}
  loading.value = false
}

// 4.16新增代理节点
// 初始化代理
const initProxyList = async (id: number) => {
  try {
    const { data, code } = await APIGetAgent({ robot_id: id })
    if (code === 200) {
      const list = []
      for (const key in data.agent) {
        list.push({
          label: data.agent[key],
          key: key
        })
      }
      proxyList.value = list
      checkboxGroup.value = data.my_agent
    }
  } catch (error) {}
}
// 更新代理
const updateAgent = async (data: { robot_id: number; agent: string }) => {
  try {
    await APIUpAgent(data)
  } catch (error) {}
}

const initKnowledgeList = async () => {
  loading.value = true
  const params = { page: 1 }
  try {
    const { data, code } = await knowledgeListApi(params)
    if (code === 200) {
      knowledgeList.value = data.list?.map((item: any) => {
        return {
          ...item,
          isCheck: false
        }
      })
    }
  } catch (error) {
    console.error(error)
  }

  loading.value = false
}

const initTrainList = async () => {
  loading.value = true
  const params = { page: 1, robot_id: props.interData.id }
  try {
    const { data, code } = await GetTrainListApi(params)
    if (code === 200) {
      trainingList.value = data.list
    }
  } catch (error) {
    console.error(error)
  }

  loading.value = false
}
onMounted(() => {
  initMemoryList(String(props.interData?.id))
  initKnowledgeList()
  initTrainList()
  initProxyList(props.interData?.id)
  upDataVoiceModel()
})

onBeforeUnmount(() => {
  Pubsub.unsubscribe("TRAINING_DATA")
})

const memoryRules = reactive<FormRules<MemoryFormProps>>({
  question: generateRule("问题"),
  answer: generateRule("答案")
})

const handleOpenTrainAndMemory = (tBool: boolean, mBool: boolean) => {
  trainVisible.value = tBool
  memoryVisible.value = mBool
}

const handleCheckList = debounce((item: KnowledgeListProps) => {
  knowledgeList.value.forEach((listItem) => {
    // 将当前项设置为 true，其他项设置为 false
    listItem.isCheck = listItem === item
  })
  knowledgeId.value = item.id
}, 200)

const handleMemory_AudioCheck = debounce((check: any, index: number) => {
  const value = check ? "1" : "2"
  modelSettingList.value[index].isCheck = check
  modelSettingList.value[index].value = value
}, 300)

const handleModelOnSubmit = debounce(async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      try {
        const { model_name, voice_id } = modelForm.value
        const modelData = {
          id: props.interData.id,
          is_memory: modelSettingList.value[0].value,
          is_audio: modelSettingList.value[1].value,
          model_name,
          voice_id: Number(voice_id)
        }

        const { data, code } = await UpdateRobotSettingApi(modelData)
        if (code === 200) {
          PubSub.publish("UPDATE_SINGLE_ROBOT")
          ElMessage({
            type: "success",
            message: "更新成功"
          })
          // modelFormRef.value?.resetFields() // 清空表单数据
          modelSettingList.value[0].value = data.is_memory
          modelSettingList.value[1].value = data.is_audio
        }

        // 更新代理
        updateAgent({ robot_id: props.interData.id, agent: checkboxGroup.value.join("##") })
      } catch (error) {
        console.error(error)
      }
    } else {
      console.log("error submit!", fields)
    }
  })
}, 300)

const handleMemoryCancel = debounce((formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
  handleOpenTrainAndMemory(false, false)
}, 200)

const handleDeleteTrainList = debounce(async (item: TrainListProps) => {
  const res = await ElMessageBox.confirm("相关训练数据将永久删除，请谨慎操作！是否继续删除？", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  })
  if (res === "confirm") {
    const { code } = await DeleteTrainApi({ id: item.id })
    if (code === 200) {
      trainingList.value = trainingList.value.filter((i) => i.id !== item.id)
      ElMessage({
        type: "success",
        message: "删除成功"
      })
    }
  }
}, 300)

const handleCopyTrainList = debounce(async (knowledge_id: number) => {
  try {
    const data = {
      robot_id: props.interData.id,
      knowledge_id
    }
    submitBtnLoading.value = true
    const { code } = await AddTrainApi(data)
    if (code === 200) {
      ElMessage({
        type: "success",
        message: "添加成功"
      })
      initTrainList()
      handleOpenTrainAndMemory(false, false)
    }
  } catch (error) {
    console.error(error)
  } finally {
    submitBtnLoading.value = false
  }
}, 300)

const handleTrainOnConfirm = debounce(() => {
  if (knowledgeList.value.length > 0) {
    handleCopyTrainList(knowledgeId.value)
  } else {
    ElMessage({
      type: "warning",
      message: "请选择所需要的训练数据"
    })
  }
}, 300)

const handleMemoryDeleteId = debounce(async (id: number, robot_id: number) => {
  const res = await ElMessageBox.confirm("相关记忆体将永久删除，请谨慎操作！是否继续删除？", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  })

  if (res === "confirm") {
    try {
      const res = await DeleteRobotIdMemory({ id })
      if (res.code === 200) {
        ElMessage({
          type: "success",
          message: "删除成功"
        })
        initMemoryList(String(robot_id))
      }
    } catch (error) {
      console.error(error)
    }
  }
}, 300)

const handleOnSubmit = debounce(async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      try {
        memoryLoading.value = true
        const data = {
          ...memoryForm,
          robot_id: props.interData.id
        }
        const res = await AddMemory(data)
        if (res.code === 200) {
          ElMessage({
            type: "success",
            message: "添加成功"
          })
          handleMemoryCancel(formEl)
          initMemoryList(String(props.interData.id))
        }
      } catch (error) {
        console.error(error)
      } finally {
        memoryLoading.value = false
      }
    } else {
      console.log("error submit!", fields)
    }
  })
}, 300)
</script>

<style lang="scss" scoped>
.checkbox-group {
  margin-top: 10px;
  :deep(.el-checkbox) {
    background: #f9f9f9;
    padding: 14px 12px;
    border-radius: 6px;
    margin-bottom: 10px;
    margin-right: 15px;
  }
  :deep(.el-checkbox__input.is-checked + .el-checkbox__label) {
    color: #606266 !important;
  }
}

.add-btn {
  height: 32px;
}
#container {
  height: 100%;
}

::v-deep .el-collapse {
  border: unset;
}

::v-deep .el-collapse .el-collapse-item__header {
  border: unset;
}

::v-deep .el-collapse .el-collapse-item__content {
  padding-bottom: 30px;

  &:last-child {
    padding-bottom: unset;
  }
}

::v-deep .el-collapse-item__wrap {
  border: unset;
}

::v-deep .el-form--label-top .el-form-item {
  margin: 0 10px 30px;
}

.arrIcon {
  margin: 10px 0;

  .icon {
    width: 26px;
    height: 26px;
    background: var(--v3-sidebar-menu-hover-bg-color);
    border-radius: 5px;
  }
}

.ft-16 {
  color: #333;
  font-family: "PingFang SC";
  font-size: 16px;
  font-style: normal;
  font-weight: 400;
  line-height: normal;
}

.ft-14 {
  font-size: 14px;
  line-height: 24px;
}

.setting-card {
  flex-shrink: 0;
  border: 1px solid #e9e9e9;
  border-radius: 10px;
  margin: 25px 0 20px;
  padding: 13px 20px;

  &:last-child {
    margin-bottom: 0;
  }
}

.avatar-img {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  flex-shrink: 0;
  background: var(--v3-sidebar-menu-hover-bg-color);
  text-align: center;

  img {
    width: 100%;
    height: 100%;
  }
}

.checkbox {
  display: flex;
  flex-direction: column;

  &-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin: 5px 0;
    padding: 7px;
    cursor: pointer;

    .right {
      width: 18px;
      height: 18px;
    }

    .isGou {
      display: none;
    }

    .left {
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }

  .checkbox-active {
    background-color: var(--v3-body-bg-color);
    border-radius: 7px;

    .isGou {
      display: block;
    }
  }
}

img {
  cursor: pointer;
}

.el-icon {
  cursor: pointer;
}

.f14333 {
  margin-left: 10px;
}

.dMemory {
  border: 1px solid var(--el-card-border-color);
  margin: 20px 0;
  border-radius: 10px;
}

.l-title {
  color: var(--el-color-info);
  font-size: 16px;
  font-weight: 600;
}

.l-answer {
  color: #666;
  font-size: 14px;
  padding-top: 10px;
}

.btn {
  padding-bottom: 30px;
}
</style>
